<template>
  <div ref="chart" :style="boxStyle" :class="className"></div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'BaseChart',
  props: {
    options: { type: Object, required: true },   // ECharts 配置
    theme: [String, Object],                      // 主题名或主题对象
    renderer: { type: String, default: 'canvas' },// 'canvas' | 'svg'
    autoresize: { type: Boolean, default: true }, // 自适应尺寸
    width: { type: [String, Number], default: '100%' },
    height: { type: [String, Number], default: 300 },
    notMerge: { type: Boolean, default: false },
    lazyUpdate: { type: Boolean, default: false },
    loading: { type: Boolean, default: false },
    className: { type: [String, Array, Object], default: '' },
    onEvents: { type: Object, default: () => ({}) } // { click: (params, chart)=>{} }
  },
  data() {
    return { chart: null, ro: null, _onWinResize: null };
  },
  computed: {
    boxStyle() {
      const n = v => (typeof v === 'number' ? v + 'px' : v);
      return { width: n(this.width), height: n(this.height) };
    }
  },
  watch: {
    options: { deep: true, handler(v) { this.setOption(v); } },
    loading(v) { if (this.chart) v ? this.chart.showLoading() : this.chart.hideLoading(); }
  },
  mounted() {
    this.initChart();
    if (this.autoresize) this.bindResize();
  },
  beforeDestroy() {
    this.unbindResize();
    if (this.chart) { this.chart.dispose(); this.chart = null; }
  },
  methods: {
    initChart() {
      if (this.chart) return;
      this.chart = echarts.init(this.$refs.chart, this.theme, { renderer: this.renderer });
      this.bindEvents();
      this.setOption(this.options, true);
      if (this.loading) this.chart.showLoading();
      this.$emit('ready', this.chart);
    },
    setOption(opt) {
      if (!this.chart || !opt) return;
      this.chart.setOption(opt, { notMerge: this.notMerge, lazyUpdate: this.lazyUpdate });
    },
    bindEvents() {
      const ev = this.onEvents || {};
      Object.keys(ev).forEach(name => {
        const fn = ev[name];
        if (typeof fn === 'function') this.chart.on(name, (...args) => fn(...args, this.chart));
      });
    },
    bindResize() {
      const el = this.$refs.chart;
      if ('ResizeObserver' in window) {
        this.ro = new ResizeObserver(() => { if (this.chart) this.chart.resize(); });
        this.ro.observe(el);
      } else {
        this._onWinResize = () => { if (this.chart) this.chart.resize(); };
        window.addEventListener('resize', this._onWinResize);
      }
    },
    unbindResize() {
      if (this.ro) { this.ro.disconnect(); this.ro = null; }
      if (this._onWinResize) { window.removeEventListener('resize', this._onWinResize); this._onWinResize = null; }
    },
    resize() { if (this.chart) this.chart.resize(); },
    getInstance() { return this.chart; },
    dispatchAction(payload) { if (this.chart) this.chart.dispatchAction(payload); }
  }
};
</script>